/*
 * Copyright (C) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

use crate::common::constants::*;
use crate::common::types::*;
use crate::log_e;
use crate::singleton_registry;
use crate::{Box, Vec};
#[cfg(any(test, feature = "test-utils"))]
use mockall::automock;

#[derive(Clone, PartialEq, Eq)]
pub struct ExecutorKey {
    pub auth_type: AuthType,
    pub sensor_hint: u32,
    pub role: ExecutorRole,
    pub device_udid: Udid,
}

#[derive(Debug, Clone, PartialEq)]
pub struct ExecutorInfo {
    pub executor_index: u64,
    pub auth_type: AuthType,
    pub matcher: u32,
    pub esl: ExecutorSecurityLevel,
    pub max_template_acl: AuthCapabilityLevel,
    pub role: ExecutorRole,
    pub sensor_hint: u32,
    pub public_key: [u8; PUBLIC_KEY_LEN],
    pub device_udid: Udid,
}

impl ExecutorInfo {
    pub fn get_key(&self) -> ExecutorKey {
        ExecutorKey {
            auth_type: self.auth_type,
            sensor_hint: self.sensor_hint,
            role: self.role,
            device_udid: self.device_udid,
        }
    }
}

pub type ExecutorFilter = Box<dyn Fn(&ExecutorInfo) -> bool>;

#[cfg_attr(any(test, feature = "test-utils"), automock)]
pub trait ExecutorManager {
    fn register(&mut self, executor_info: &ExecutorInfo) -> Result<u64, ErrorCode>;
    fn unregister(&mut self, executor_index: u64) -> ();
    fn get_executor(&self, filter: ExecutorFilter) -> Result<ExecutorInfo, ErrorCode>;
    fn get_executor_list(&self, filter: ExecutorFilter) -> Vec<ExecutorInfo>;
    fn get_executor_matcher(&self, _filter: ExecutorFilter) -> Result<u32, ErrorCode>;
    fn get_min_esl(&mut self, _executor_info_list: &Vec<ExecutorInfo>) -> Result<u32, ErrorCode>;
}

pub struct DummyExecutorManager;

impl ExecutorManager for DummyExecutorManager {
    fn register(&mut self, _executor_info: &ExecutorInfo) -> Result<u64, ErrorCode> {
        log_e!("not implemented");
        Err(ErrorCode::GeneralError)
    }

    fn unregister(&mut self, _executor_index: u64) -> () {
        log_e!("not implemented");
    }

    fn get_executor(&self, _filter: ExecutorFilter) -> Result<ExecutorInfo, ErrorCode> {
        log_e!("not implemented");
        Err(ErrorCode::GeneralError)
    }

    fn get_executor_list(&self, _filter: ExecutorFilter) -> Vec<ExecutorInfo> {
        log_e!("not implemented");
        Vec::new()
    }

    fn get_executor_matcher(&self, _filter: ExecutorFilter) -> Result<u32, ErrorCode> {
        log_e!("not implemented");
        Err(ErrorCode::GeneralError)
    }

    fn get_min_esl(&mut self, _executor_info_list: &Vec<ExecutorInfo>) -> Result<u32, ErrorCode> {
        log_e!("not implemented");
        Err(ErrorCode::GeneralError)
    }
}

singleton_registry!(
    ExecutorManagerRegistry,
    ExecutorManager,
    DummyExecutorManager
);
